﻿namespace NTLib.Application
{
    using Core.Exceptions;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows;

    /// <summary>
    /// 
    /// </summary>
    public abstract class DispatchHelper
    {
        #region Fields

        private static DispatchHelper s_instance;
        //private static Dispatcher s_dispatcher;

        #endregion

        #region Ctor

        /// <summary>
        /// Dispatches the helper.
        /// </summary>
        protected DispatchHelper()
        {
            if (s_instance != null)
                throw new SingletonException(this.GetType());
            s_instance = this;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the instance.
        /// </summary>
        public static DispatchHelper Instance
        {
            get { return s_instance; }
        }
        /// <summary>
        /// Gets the UI dispatcher.
        /// </summary>
        //public static Dispatcher UIDispatcher
        //{
        //    get
        //    {
        //        if (s_dispatcher == null)
        //        {
        //            if (Application.Current == null)
        //                s_dispatcher = Dispatcher.FromThread(Thread.CurrentThread);
        //            else
        //                s_dispatcher = Application.Current.Dispatcher;
        //        }
        //        return s_dispatcher;
        //    }
        //}

        #endregion

        #region Methods

        /// <summary>
        /// Execut the action in the dispatcher context.
        /// </summary>
        /// <param name="action">The action.</param>
        public abstract void DispatchExec(Action action);
        //{
        //    var dispatcher = UIDispatcher;
        //    if (Thread.CurrentThread.ManagedThreadId == dispatcher.Thread.ManagedThreadId)
        //        action();
        //    else
        //        dispatcher.Invoke(action);
        //}

        /// <summary>
        /// Execut the action in the dispatcher context.
        /// </summary>
        /// <param name="asyncaction">The async action.</param>
        /// <param name="token">The cancellation token.</param>
        public abstract Task DispatchExecAsync(Func<CancellationToken, Task> asyncaction, CancellationToken token = default(CancellationToken));
        //{
        //    var dispatcher = UIDispatcher;
        //    if (Thread.CurrentThread.ManagedThreadId == dispatcher.Thread.ManagedThreadId)
        //        await asyncaction(token);
        //    else
        //        await dispatcher.BeginInvoke(asyncaction, token);
        //}

        /// <summary>
        /// Execut the action in the dispatcher context.
        /// </summary>
        /// <param name="asyncaction">The asyncaction.</param>
        /// <param name="token">The token.</param>
        /// <returns></returns>
        public abstract Task DispatchExecAsync(Action<CancellationToken> asyncaction, CancellationToken token = default(CancellationToken));
        //{
        //    var dispatcher = UIDispatcher;
        //    if (Thread.CurrentThread.ManagedThreadId == dispatcher.Thread.ManagedThreadId)
        //        asyncaction(token);
        //    else
        //        await dispatcher.BeginInvoke(asyncaction, token);
        //}

        #endregion
    }
}
